`include "global_def.h"

module Decode(
  I_CLOCK,
  I_LOCK,
  I_PC,
  I_IR,
  I_FetchStall,
  I_WriteBackEnable,
  I_WriteBackRegIdx,
  I_WriteBackData,
  I_VectorWriteBackRegIdx,
  I_VectorWriteBackData,
  I_VectorWriteBackEnable,
  I_RAST_STALL,
  O_LOCK,
  O_PC,
  O_Opcode,
  O_Src1Value,
  O_Src2Value,
  O_DestRegIdx,
//  O_DestValue, //Not needed
  O_Imm,
  O_FetchStall,
  O_DepStall,
  O_BranchStallSignal,
  O_DepStallSignal,
  O_VectorSrc1Value, //New
  O_VectorSrc2Value,
  O_VectorDestRegIdx,
//  O_VectorDestValue,
  O_Idx
//  O_VectorImm //End New
);

/////////////////////////////////////////
// IN/OUT DEFINITION GOES HERE
/////////////////////////////////////////
//
// Inputs from the fetch stage
input I_CLOCK; //Actually not from fetch, but whatever
input I_LOCK;
input [`PC_WIDTH-1:0] I_PC;
input [`IR_WIDTH-1:0] I_IR;
input I_FetchStall;
input I_RAST_STALL; //Stall from Rasterisation

// Inputs from the writeback stage
input I_WriteBackEnable;
input [3:0] I_WriteBackRegIdx;
input [`REG_WIDTH-1:0] I_WriteBackData;

// Vector Inputs from the writeback stage
input I_VectorWriteBackEnable;
input [5:0] I_VectorWriteBackRegIdx;
input [`VREG_WIDTH-1:0] I_VectorWriteBackData;

// Outputs to the execute stage
output reg O_LOCK;
output reg [`PC_WIDTH-1:0] O_PC;
output reg [`OPCODE_WIDTH-1:0] O_Opcode;
output reg [`REG_WIDTH-1:0] O_Src1Value;
output reg [`REG_WIDTH-1:0] O_Src2Value;
output reg [3:0] O_DestRegIdx;
//output reg [`REG_WIDTH-1:0] O_DestValue; //Not needed
output reg [`REG_WIDTH-1:0] O_Imm;
output reg O_FetchStall;

// Vector outputs to the execute stage
output reg [`VREG_WIDTH-1:0] O_VectorSrc1Value;
output reg [`VREG_WIDTH-1:0] O_VectorSrc2Value;
output reg [5:0] O_VectorDestRegIdx;
output reg [1:0] O_Idx;
//output reg [`VREG_WIDTH-1:0] O_VectorDestValue; //Not needed
//output reg [`VREG_WIDTH-1:0] O_VectorImm; //Not needed

/////////////////////////////////////////
// ## Note ##
// O_DepStall: Asserted when current instruction should be waiting for data dependency resolves. 
// - Like O_FetchStall, the instruction with O_DepStall == 1 will be treated as NOP in the following stages.
/////////////////////////////////////////
output reg O_DepStall;  

// Outputs to the fetch stage
output O_DepStallSignal;
output O_BranchStallSignal;

/////////////////////////////////////////
// WIRE/REGISTER DECLARATION GOES HERE
/////////////////////////////////////////
//
// Architectural Registers
reg [`REG_WIDTH-1:0] RF[0:`NUM_RF-1]; // Scalar Register File (R0-R7: Integer, R8-R15: Floating-point)
reg [`VREG_WIDTH-1:0] VRF[0:`NUM_VRF-1]; // Vector Register File

// Valid bits for tracking the register dependence information
reg RF_VALID[0:`NUM_RF-1]; // Valid bits for Scalar Register File
reg VRF_VALID[0:`NUM_VRF-1]; // Valid bits for Vector Register File

//wire [`REG_WIDTH-1:0] Imm16; // Sign-extended immediate value
reg [2:0] ConditionalCode; // Set based on the written-back result

reg [2:0] BRCounter;
reg PCSaved;

/////////////////////////////////////////
// INITIAL/ASSIGN STATEMENT GOES HERE
/////////////////////////////////////////
//
reg[7:0] trav;

initial
begin
  for (trav = 0; trav < `NUM_RF; trav = trav + 1'b1)
  begin
    RF[trav] = 0;
    RF_VALID[trav] = 1;  
  end 

  for (trav = 0; trav < `NUM_VRF; trav = trav + 1'b1)
  begin
    VRF[trav] = 0;
    VRF_VALID[trav] = 1;  
  end 

  ConditionalCode = 0;

  O_PC = 0;
  O_Opcode = 0;
  O_DepStall = 0;
  
  BRCounter = 0;
  PCSaved = 0;
end // initial


/////////////////WIRES///////////////////////

// Branch instruction detected (1) or not (0).
wire __BranchSignal;
assign __BranchSignal = 
  ((I_LOCK == 1'b1) ? 
    ((I_IR[31:24] == `OP_BRN  ) ? (1'b1) : 
     (I_IR[31:24] == `OP_BRZ  ) ? (1'b1) : 
     (I_IR[31:24] == `OP_BRP  ) ? (1'b1) : 
     (I_IR[31:24] == `OP_BRNZ ) ? (1'b1) : 
     (I_IR[31:24] == `OP_BRNP ) ? (1'b1) : 
     (I_IR[31:24] == `OP_BRZP ) ? (1'b1) : 
     (I_IR[31:24] == `OP_BRNZP) ? (1'b1) : 
//     (I_IR[31:24] == `OP_JMP  ) ? (1'b1) : 
//     (I_IR[31:24] == `OP_JSR  ) ? (1'b1) : 
//     (I_IR[31:24] == `OP_JSRR ) ? (1'b1) : 
     (1'b0) //no branch
    ) : (1'b0)); //I_LOCK == 0

//JMP and RET
wire __JMPSignal;
assign __JMPSignal = 
	((I_LOCK == 1'b1) ?
		((I_IR[31:24] == `OP_JMP  ) ? (1'b1) :
		 (1'b0) //no JMP (or RET, since OPCode is the same)
		) : (1'b0)); //I_LOCK == 0

//JSR or JSRR
wire __JSRSignal;
assign __JSRSignal = 
	((I_LOCK == 1'b1) ?
		((I_IR[31:24] == `OP_JSR  ) ? (1'b1) :
		 (I_IR[31:24] == `OP_JSRR ) ? (1'b1) : 
		 (1'b0) //no JSR
		) : (1'b0)); //I_LOCK == 0


//////////////////////////////////////////////////////////////////////////////////////////////
// This will be 1 when the instruction from Fetch has a dependency issue with an invalid reg.
// Takes into account the register currently being updated by Writeback.
//////////////////////////////////////////////////////////////////////////////////////////////
wire __DepStallSignal;
assign __DepStallSignal = 
	((I_LOCK == 1'b1)?
		(((I_IR[31:24] == `OP_ADDI_D) || (I_IR[31:24] == `OP_ANDI_D) || (I_IR[31:24] == `OP_LDW) || (I_IR[31:24] == `OP_STW))?
			((I_WriteBackEnable == 0)? 														//If either are invalid and no WB, stall
				((RF_VALID[I_IR[19:16]] == 0) || (RF_VALID[I_IR[23:20]] == 0)): 
			(((RF_VALID[I_IR[19:16]] == 0) && (RF_VALID[I_IR[23:20]] == 0))? 		//If both are invalid, stall
					(1'b1):
			(((RF_VALID[I_IR[19:16]] == 0) && (I_WriteBackRegIdx != I_IR[19:16]))? //If RegA's invalid and doesn't match the WB, stall
					(1'b1):
			(((RF_VALID[I_IR[23:20]] == 0) && (I_WriteBackRegIdx != I_IR[23:20]))? //If RegB's invalid and doesn't match the WB, stall
					(1'b1):
					(1'b0))))): //Otherwise, don't stall

		((I_IR[31:24] == `OP_ADD_D) || (I_IR[31:24] == `OP_AND_D))?
			((I_WriteBackEnable == 0)?					//If any are invalid and no WB, stall
				((RF_VALID[I_IR[19:16]] == 0) || (RF_VALID[I_IR[23:20]] == 0) || (RF_VALID[I_IR[11:8]] == 0)):
			(((RF_VALID[I_IR[19:16]] == 0) && (RF_VALID[I_IR[11:8]] == 0))? //If any 2 are invalid, stall
				(1'b1):
			(((RF_VALID[I_IR[19:16]] == 0) && (RF_VALID[I_IR[23:20]] == 0))?
				(1'b1):
			(((RF_VALID[I_IR[11:8]] == 0) && (RF_VALID[I_IR[23:20]] == 0))?
				(1'b1):
			(((RF_VALID[I_IR[19:16]] == 0) && (I_WriteBackRegIdx != I_IR[19:16]))? //If RegA's invalid and doesn't match WB, stall
				(1'b1):
			(((RF_VALID[I_IR[11:8]] == 0) && (I_WriteBackRegIdx != I_IR[11:8]))? //If RegB's invalid and doesn't match WB, stall
				(1'b1):
			(((RF_VALID[I_IR[23:20]] == 0) && (I_WriteBackRegIdx != I_IR[23:20]))? //If RegC's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0)))))))): //Otherwise, don't stall
	
		((I_IR[31:24] == `OP_MOVI_D) || (I_IR[31:24] == `OP_JMP) || (I_IR[31:24] == `OP_RET) || (I_IR[31:24] == `OP_JSRR))?
			((I_WriteBackEnable == 0)? 						//If it's invalid and no WB, stall
				(RF_VALID[I_IR[19:16]] == 0):
			(((RF_VALID[I_IR[19:16]] == 0) && (I_WriteBackRegIdx != I_IR[19:16]))? //If it's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0))): //Otherwise, don't stall
				
		((I_IR[31:24] == `OP_VMOVI) || (I_IR[31:24] == `OP_VCOMPMOVI) || (I_IR[31:24] == `OP_SETVERTEX) || (I_IR[31:24] == `OP_SETCOLOR) || (I_IR[31:24] == `OP_ROTATE) || (I_IR[31:24] == `OP_TRANSLATE) || (I_IR[31:24] == `OP_SCALE))?
			((I_VectorWriteBackEnable == 0)? 						//If it's invalid and no WB, stall
				(VRF_VALID[I_IR[21:16]] == 0):
			(((VRF_VALID[I_IR[21:16]] == 0) && (I_VectorWriteBackRegIdx != I_IR[21:16]))? //If it's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0))):
		
		(I_IR[31:24] == `OP_VCOMPMOV)?
			((I_VectorWriteBackEnable == 0)? 					//If either are invalid and no WB, stall
				((VRF_VALID[I_IR[21:16]] == 0) || (RF_VALID[I_IR[11:8]] == 0)):
			(((VRF_VALID[I_IR[21:16]] == 0) && (RF_VALID[I_IR[11:8]] == 0))? //If they're both invalid, stall
				(1'b1):
			(((VRF_VALID[I_IR[21:16]] == 0) && (I_VectorWriteBackRegIdx != I_IR[21:16]))? //If RegA's invalid and doesn't match WB, stall
				(1'b1):
			(((RF_VALID[I_IR[11:8]] == 0) && (I_WriteBackRegIdx != I_IR[11:8]))? //If RegB's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0))))):
				
		((I_IR[31:24] == `OP_VADD))?
			((I_VectorWriteBackEnable == 0)?					//If any are invalid and no WB, stall
				((VRF_VALID[I_IR[21:16]] == 0) || (VRF_VALID[I_IR[13:8]] == 0) || (VRF_VALID[I_IR[5:0]] == 0)):
			(((VRF_VALID[I_IR[21:16]] == 0) && (VRF_VALID[I_IR[13:8]] == 0))? //If any 2 are invalid, stall
				(1'b1):
			(((VRF_VALID[I_IR[21:16]] == 0) && (VRF_VALID[I_IR[5:0]] == 0))?
				(1'b1):
			(((VRF_VALID[I_IR[13:8]] == 0) && (VRF_VALID[I_IR[5:0]] == 0))?
				(1'b1):
			(((VRF_VALID[I_IR[21:16]] == 0) && (I_VectorWriteBackRegIdx != I_IR[21:16]))? //If RegA's invalid and doesn't match WB, stall
				(1'b1):
			(((VRF_VALID[I_IR[13:8]] == 0) && (I_VectorWriteBackRegIdx != I_IR[13:8]))? //If RegB's invalid and doesn't match WB, stall
				(1'b1):
			(((VRF_VALID[I_IR[5:0]] == 0) && (I_VectorWriteBackRegIdx != I_IR[5:0]))? //If RegC's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0)))))))):
				
		(I_IR[31:24] == `OP_VMOV)?
			((I_VectorWriteBackEnable == 0)? 					//If either are invalid and no WB, stall
				((VRF_VALID[I_IR[21:16]] == 0) || (VRF_VALID[I_IR[13:8]] == 0)):
			(((VRF_VALID[I_IR[21:16]] == 0) && (VRF_VALID[I_IR[13:8]] == 0))? //If they're both invalid, stall
				(1'b1):
			(((VRF_VALID[I_IR[21:16]] == 0) && (I_VectorWriteBackRegIdx != I_IR[21:16]))? //If RegA's invalid and doesn't match WB, stall
				(1'b1):
			(((VRF_VALID[I_IR[13:8]] == 0) && (I_VectorWriteBackRegIdx != I_IR[13:8]))? //If RegB's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0))))):

		(I_IR[31:24] == `OP_MOV)?
			((I_WriteBackEnable == 0)? 					//If either are invalid and no WB, stall
				((RF_VALID[I_IR[19:16]] == 0) || (RF_VALID[I_IR[11:8]] == 0)):
			(((RF_VALID[I_IR[19:16]] == 0) && (RF_VALID[I_IR[11:8]] == 0))? //If they're both invalid, stall
				(1'b1):
			(((RF_VALID[I_IR[19:16]] == 0) && (I_WriteBackRegIdx != I_IR[19:16]))? //If RegA's invalid and doesn't match WB, stall
				(1'b1):
			(((RF_VALID[I_IR[11:8]] == 0) && (I_WriteBackRegIdx != I_IR[11:8]))? //If RegB's invalid and doesn't match WB, stall
				(1'b1):
				(1'b0))))): //Otherwise don't stall
		(1'b0)): //If none of the opcodes match...don't dependency stall, I guess (but you probably have bigger problems).
	(1'b0)); //If (I_LOCK == 0), this will make __DepStallSignal default to 0.


/////////////////////////////////////////////////////////////////////////////
//Sometimes we need Fetch to stall for reasons other than a dependency 
//(when we need an extra cycle to save PC into R7, for instance,
//or when we need to stall for BR before checking CC's
/////////////////////////////////////////////////////////////////////////////
wire __BRDepSignal;
assign __BRDepSignal = 
	( (I_LOCK == 1'b1)? ( 
		((BRCounter > 1) || ((BRCounter == 0) && (__BranchSignal)) || 
							((__JSRSignal) && (PCSaved == 0))) ?
			(1'b1) :
			(1'b0)): //else
		(1'b0) ); //If (I_LOCK == 0), this will make __BRDepSignal default to 0.

/////////////////////////////////////////////////////////////////////////////
//Stall Fetch if either of those things happen (Dependency or... misc)
/////////////////////////////////////////////////////////////////////////////
assign O_DepStallSignal = ((__DepStallSignal || __BRDepSignal) && (!I_FetchStall) && (!I_RAST_STALL));


/////////////////////////////////////////////////////////////////////////////
//This will be 1 when a branch is going to happen (Either unconditional jumps
//or when BR resolves successfully)
/////////////////////////////////////////////////////////////////////////////
wire __BranchComingSignal;
assign __BranchComingSignal = 
	( (I_LOCK == 1'b1)? (
		(PCSaved) || (__JMPSignal) ||
		( (BRCounter == 1) && ( ((I_IR[26] == 1'b1) && (ConditionalCode[2] == 1'b1)) ||
				((I_IR[25] == 1'b1) && (ConditionalCode[1] == 1'b1)) || 
				((I_IR[24] == 1'b1) && (ConditionalCode[0] == 1'b1))) ) ?
			(1'b1) :
			(1'b0)): //else
		(1'b0) ); //If (I_LOCK == 0), this will make __BRDepSignal default to 0.

/////////////////////////////////////////////////////////////////////////////
//Let Fetch know a branch is coming when....uh... a branch is coming
/////////////////////////////////////////////////////////////////////////////
assign O_BranchStallSignal = ((__BranchComingSignal) && ((!I_FetchStall) && (!I_RAST_STALL)));


/////////////////////////////////////////
// ALWAYS STATEMENT GOES HERE
/////////////////////////////////////////
// ## Note ##
// First half clock cycle to write data back into the register file 
// 1. To write data back into the register file
// 2. Update Conditional Code to the following branch instruction to refer
/////////////////////////////////////////
always @(posedge I_CLOCK)
begin
	if (!I_RAST_STALL) begin
	  if (I_LOCK == 1'b1)
	  begin
			if(I_WriteBackEnable) begin
			
				//Write Data back
				RF[I_WriteBackRegIdx] <= I_WriteBackData;
				
				//Set CC bits
				if(I_WriteBackData[15] == 1'b1)begin //checking the negative bit (assuming verilog likes this)
					ConditionalCode <= 3'b100;
				end
				else if(I_WriteBackData == 16'h0)begin //checking zero
					ConditionalCode <= 3'b010;
				end
				else begin
					ConditionalCode <= 3'b001; //positive
				end			
			end else if(I_VectorWriteBackEnable) begin
				//Write Data back
				VRF[I_VectorWriteBackRegIdx] <= I_VectorWriteBackData;			
			end
	  end // if (I_LOCK == 1'b1)
	 end // if (!I_RAST_STALL)
end // always @(posedge I_CLOCK)

/////////////////////////////////////////
// ## Note ##
// Second half clock cycle to read data from the register file
// 1. To read data from the register file
// 2. To update valid bit for the corresponding register (for both writeback instruction and current instruction) 
/////////////////////////////////////////
always @(negedge I_CLOCK)
begin
	if (!I_RAST_STALL) begin
		//Initialize output reg's
		O_LOCK <= I_LOCK;
		O_FetchStall <= I_FetchStall;
		O_PC <= I_PC;
		O_Opcode <= I_IR[31:24];
		O_Imm <= I_IR[15:0];
		
		if (I_WriteBackEnable) begin
			RF_VALID[I_WriteBackRegIdx] <= 1;
		end
		
		else if (I_VectorWriteBackEnable) begin
			VRF_VALID[I_VectorWriteBackRegIdx] <= 1;
		end

		////////////////////I_LOCK == 0
		if (!I_LOCK) begin
			O_DepStall <= 1'b0;
		end

	  else //////////////////I_LOCK == 1
	  begin
	  
		 //Dependency detected
		 if (__DepStallSignal) begin
			//We have a dependency issue: Fetch will stall
			//Nop forward
			O_DepStall <= 1'b1;	 
		 end
	  
		 //Fetch is stalling
		 else if (I_FetchStall) begin 
			//Fetch is stalling, treat as a nop: Do nothing
			//No need to nop forwad, fetch's nop will be passed along automatically
			O_DepStall <= 1'b0;
		 end

		 
		 ///////////BR STUFF///////////
		 else if (BRCounter > 1) begin
			//Stall one more cycle
			BRCounter <= (BRCounter - 3'b1);
			
			O_DepStall <= 1'b1;
		 end
		 
		 else if (BRCounter == 1) begin
			//Finished 2-cycle stall, determine if branching or not
			
			//If branching, tell fetch branch, stop stalling it, don't stall forward anymore
			if ( ((I_IR[26] == 1'b1) && (ConditionalCode[2] == 1'b1)) ||
					((I_IR[25] == 1'b1) && (ConditionalCode[1] == 1'b1)) || 
					((I_IR[24] == 1'b1) && (ConditionalCode[0] == 1'b1))) begin //Branch
				O_DepStall <= 0;
			end
			
			//Otherwise, no branch: pass a nop forward
			else begin
				//Stall execute one more time
				O_DepStall <= 1;
			end
			
			//Either way, reset counter
			BRCounter <= 0;
		 end
		 ///////////END BR STUFF///////////

		 
		 ///////////JSR STUFF///////////////
		 else if (PCSaved == 1) begin //We saved PC, do the JSR(R) now
			O_DepStall <= 1'b0;
			O_Src1Value <= RF[I_IR[19:16]];
			//Reset counter
			PCSaved <= 0;
		 end
		 ///////////END JSR STUFF/////////////

		 
		 //BR detected
		 else if (__BranchSignal) begin
			//So, we have a new BR instruction. Stall fetch, pass nops for 2 cycles
			O_DepStall <= 1'b1;
			BRCounter <= 2;
		 end
		 
	//	 //JMP/RET detected
	//	 else if (__JMPSignal) begin
	//		//JMP or RET: Let Fetch know a branch is coming
	//		O_BranchStallSignal <= 1'b1;
	//	 end


		 //JSR/JSRR detected
		 else if (__JSRSignal) begin
			//[JSR or JSRR: R7 <- PC, Let fetch know branch is coming]
			// Here, we need to stall fetch, and pass Execute an intermediate instruction to store PC into R7:
			//		MOVI R7 (PC_Value)       <-- this will require setting O_Imm, O_OPCode and O_DestRegIdx appropriately
			
			//Tells execute to store PC into R7
			O_Opcode <= `OP_MOVI_D;
			O_Imm <= I_PC;
			O_DestRegIdx <= 4'b0111;
			RF_VALID[7] <= 0;
			
			//PC is saved
			PCSaved <= 1'b1;
			
			O_DepStall <= 1'b0;
		 end

		 /////////////////////////Normal Operation//////////////////////////
		 else begin
			 O_DepStall <= 1'b0;
		 
			 //Set DestRegIdx
			 if ((I_IR[31:24] == `OP_ADD_D) || (I_IR[31:24] == `OP_ADDI_D) || (I_IR[31:24] == `OP_AND_D) || (I_IR[31:24] == `OP_ANDI_D) || (I_IR[31:24] == `OP_LDW)) begin
				O_DestRegIdx <= I_IR[23:20];
				RF_VALID[I_IR[23:20]] <= 0;
			 end
			 else if ((I_IR[31:24] == `OP_MOV) || (I_IR[31:24] == `OP_MOVI_D)) begin
				O_DestRegIdx <= I_IR[19:16];
				RF_VALID[I_IR[19:16]] <= 0;
			 end
			 else begin
				O_DestRegIdx <= 0;
			 end
			 
			 //Set Src1Value
			 if ((I_IR[31:24] == `OP_ADD_D) || (I_IR[31:24] == `OP_ADDI_D) || (I_IR[31:24] == `OP_AND_D) || (I_IR[31:24] == `OP_ANDI_D) || (I_IR[31:24] == `OP_LDW) || (I_IR[31:24] == `OP_JMP) || (I_IR[31:24] == `OP_RET) || (I_IR[31:24] == `OP_JSRR)) begin
				O_Src1Value <= RF[I_IR[19:16]];
			 end
			 else if ((I_IR[31:24] == `OP_MOV) || (I_IR[31:24] == `OP_VCOMPMOV)) begin
				O_Src1Value <= RF[I_IR[11:8]];
			 end
			 else if (I_IR[31:24] == `OP_STW) begin
				O_Src1Value <= RF[I_IR[23:20]];
			 end
			 else begin
				O_Src1Value <= 0;
			 end
			 
			 //Set Src2Value
			 if ((I_IR[31:24] == `OP_ADD_D) || (I_IR[31:24] == `OP_AND_D)) begin
				O_Src2Value <= RF[I_IR[11:8]];
			 end
			 else if (I_IR[31:24] == `OP_STW) begin
				O_Src2Value <= RF[I_IR[19:16]];
			 end
			 else begin
				O_Src2Value <= 0;
			 end
			 
			 //Set VectorDestRegIdx
			 if ((I_IR[31:24] == `OP_VADD) || (I_IR[31:24] == `OP_VMOV) || (I_IR[31:24] == `OP_VMOVI) || (I_IR[31:24] == `OP_VCOMPMOV) || (I_IR[31:24] == `OP_VCOMPMOVI)) begin
				O_VectorDestRegIdx <= I_IR[21:16];
				VRF_VALID[I_IR[21:16]] <= 0;
				O_Idx <= I_IR[23:22];
			end
			
			//Set VectorSrc1Value
			if ((I_IR[31:24] == `OP_VADD) || (I_IR[31:24] == `OP_VMOV)) begin
				O_VectorSrc1Value <= VRF[I_IR[13:8]];
			end
			else if((I_IR[31:24] == `OP_VCOMPMOV) || (I_IR[31:24] == `OP_VCOMPMOVI) || (I_IR[31:24] == `OP_SETVERTEX) || (I_IR[31:24] == `OP_SETCOLOR) || (I_IR[31:24] == `OP_ROTATE) || (I_IR[31:24] == `OP_TRANSLATE) || (I_IR[31:24] == `OP_SCALE)) begin
				O_VectorSrc1Value <= VRF[I_IR[21:16]];
			end
			else if(I_IR[31:24] == `OP_BEGINPRIMITIVE) begin
				O_VectorSrc1Value[63:4] <= 60'b0;
				O_VectorSrc1Value[3:0] <= I_IR[19:16];
			end
			
			//Set VectorSrc2Value
			if ((I_IR[31:24] == `OP_VADD)) begin
				O_VectorSrc2Value <= VRF[I_IR[5:0]];
			end
			
	//		//Set VectorImm
	//		if ((I_IR[31:24] == `OP_VMOVI) || (I_IR[31:24] == `OP_VCOMPMOVI)) begin
	//			O_VectorImm <= I_IR[16:0];
	//		end

		 end

	  end // if (I_LOCK == 1'b1)
	end // if (!I_RAST_STALL)
end // always @(negedge I_CLOCK)

/////////////////////////////////////////
// COMBINATIONAL LOGIC GOES HERE
/////////////////////////////////////////
//
//SignExtension SE0(.In(I_IR[15:0]), .Out(Imm16));

endmodule // module Decode
